package Client;


import java.applet.*;
import java.awt.*;
import java.net.*;
import java.util.Vector;

class clientwindow extends Frame implements Runnable {
	static final int PLAYER1 = 1;
	static final int PLAYER2 = 2;
	private gameclient gclient = new gameclient();
	private String text, opponent_temp;
	private Vector id_vector = new Vector(1, 1);
	private boolean game_on = false;
	private boolean move_received = false;
	private boolean finish = false;
	private boolean challenged = false;
	private int player = PLAYER1; // who is player 1
	private int other_player = PLAYER2; // who is player 2
	private int opponent_id; // store id of opponent
	private int personal_id; // store your id
	private String nextMoveBuffer; // store next move made

	private URL base;
	private int port;
	private Thread thread;
	private int battle_id;

	private Label userlabel;
	private Label userlabel2;
	private Label userlabel3;
	private Panel mypanel;
	private String Username;
	private List user_list;
	private TextArea textArea;
	private TextField textField;
	private Color bk_color;
	private Color fg_color;
	private Color bx_color;
	private boolean statusflag = false;
	private Image gameimage;
	private graphicpanel gp;
	private game mygame; // User fills this class in
	Applet myapplet;

	clientwindow(Applet theapplet, URL base_url, int theport, String User,
			Image image) {
		myapplet = theapplet;
		base = base_url;
		port = theport;
		Username = User;
		gameimage = image;
		int framewidth = 410;
		int frameheight = 540;

		bk_color = new Color(90, 90, 90);
		fg_color = new Color(255, 206, 140);
		bx_color = new Color(2, 29, 15);

		this.setSize(framewidth, frameheight);
		this.setTitle("Client-Server Communications Window");
		this.setBackground(Color.black);
		this.setForeground(Color.black);
		this.setLayout(null);

		gp = new graphicpanel(gameimage);
		gp.setLocation(60, 30);
		gp.setSize(300, 100);
		this.add(gp);

		// userlabel = new Label();
		// userlabel.setText(" " + User);
		// userlabel.setFont(new Font("Helvetica",Font.PLAIN,16));
		// userlabel.setForeground(Color.white);
		// userlabel.setBackground(Color.black);
		// userlabel.setLocation(framewidth / 4, 70);
		// userlabel.setSize(100,30);
		// this.add(userlabel);

		mypanel = new Panel();
		mypanel.setLayout(new BorderLayout());

		userlabel2 = new Label();
		userlabel2
				.setText("      List of Players Waiting -> to Play Double Click One");
		userlabel2.setFont(new Font("Helvetica", Font.PLAIN, 16));
		userlabel2.setForeground(Color.white);
		userlabel2.setBackground(Color.black);
		mypanel.add(userlabel2, BorderLayout.NORTH);

		user_list = new List();
		user_list.setBackground(Color.blue);
		user_list.setForeground(Color.white);
		mypanel.add(user_list, BorderLayout.CENTER);

		mypanel.setLocation(4, 135);
		mypanel.setSize(framewidth - 5, 200);
		this.add(mypanel);

		userlabel3 = new Label();
		userlabel3
				.setText("  Type in red box below & hit c/r to send msg to Opponent");
		userlabel3.setFont(new Font("Helvetica", Font.PLAIN, 16));
		userlabel3.setForeground(Color.white);
		userlabel3.setBackground(Color.black);
		userlabel3.setLocation(1, 340);
		userlabel3.setSize(framewidth, 30);
		this.add(userlabel3);

		textField = new TextField(41);
		textField.setFont(new Font("Helvetica", Font.PLAIN, 16));
		textField.setBackground(Color.red);
		textField.setForeground(Color.white);
		textField.setLocation(1, 370);
		textField.setSize(framewidth, 30);
		this.add(textField);

		textArea = new TextArea(41, 8);
		textArea.setFont(new Font("Helvetica", Font.PLAIN, 14));
		textArea.setBackground(Color.white);
		textArea.setForeground(Color.black);
		textArea.setEditable(false);
		textArea.setLocation(1, 400);
		textArea.setSize(framewidth, 100);

		this.add(textArea);

		this.setSize(framewidth, frameheight);
		this.show();
		this.start(); // start this thread via contructor
	}

	// gets the thread going
	public void start() {
		System.out.println("starting thread");
		thread = new Thread(this, "main");
		thread.start();
	}

	public void run() {
		System.out.println("RUN ing thread");

		display("Trying to connect to socket...\n");
		System.out.println("server port is " + port);
		System.out.println("URL is " + base.getHost());
		statusflag = gclient.connect(base.getHost(), port);
		if (!statusflag) {
			display("Unable to to connect, gameServer is probably down...\n");
		} else {
			display("Connected to Socket!!!\n");
			String textstream = Username;
			gclient.send_stream("!!name!!" + textstream);
			System.out.println("gclient.send_stream username sent is "
					+ textstream);
		}

		while (true) {

			try {
				thread.sleep(50);
			} catch (InterruptedException e) {
			}

			if (gclient.running())
				continue;
			if (gclient.input_stream_available()) {
				text = gclient.get_input();
				if (gclient.is_nameslist(text))
					write_list(text.substring(9));
				if (gclient.is_directive(text))
					processDirective(text.substring(13));
				if (!gclient.is_directive(text) && !gclient.is_nameslist(text))
					display(text);
			}
		}
	}

	// If directive, deal with it according to the message that is attached
	public void processDirective(String text) {

		String temp;
		int next, temp_id, opp_id;
		temp = text;
		text = text.substring(6);
		char next_char;

		// if the directive is a challenge...

		if (temp.startsWith("chlng")) {
			next = text.indexOf(',');
			temp = text.substring(0, next);
			if (!game_on) {
				opponent_id = Integer.parseInt(temp);
				text = text.substring(next + 1);
				temp = text.substring(0);
				opponent_temp = temp.trim();
				player = PLAYER2;
				other_player = PLAYER1;
				challenged = true;
				display("You have been asked to Play by " + temp);
				display("hit the 'Play Opponent' button to Play\n");
				acceptwindow accept = new acceptwindow(this,
						"Do You Want to Play ", temp);
			} else {
				opp_id = Integer.parseInt(temp);
				temp_id = id_vector.indexOf(new Integer(opp_id));
				battle_id = id_vector.indexOf(new Integer(opp_id));
				gclient.send_stream("!!directive!!mssge,busy|"
						+ Integer.toString(temp_id + 1) + "|");
			}
		}

		// if the directive is a message...
		if (temp.startsWith("mssge")) {
			if (text.startsWith("uid")) {
				temp = text.substring(4);
				personal_id = Integer.parseInt(temp.trim());
			}
			if (text.startsWith("busy"))
				display("That player is currently playing a game...\n");
			if (text.startsWith("surrender")) {
				display("Your opponent has surrendered\n");
				game_on = false;
			}
		}

		// if directive is an accept challenge...
		if (temp.startsWith("accpt") && !challenged) {
			next = text.indexOf(',');
			temp = text.substring(0, next);
			temp_id = Integer.parseInt(temp.trim());
			if (temp_id == opponent_id) {
				text = text.substring(next + 1);
				game_on = true;
				player = PLAYER1;
				other_player = PLAYER2;
				challenged = false;
				display("GAME ON!! you go first\n");
				mygame = new game(myapplet, base, this, true, gameimage);

			}
		}

		// if directive is a move
		if (temp.startsWith("pmove")) {
			next = text.indexOf(',');
			temp = text.substring(0, next);
			move_received = true;
			nextMoveBuffer = temp;
			mygame.set_opponent_move(nextMoveBuffer); // calls game method
		}
	}

	public void quitWindow() {
		int index;

		display("Preparing to log off.\n");
		if (game_on) {
			index = id_vector.indexOf(new Integer(opponent_id));
			gclient.send_stream("!!directive!!mssge,surrender|"
					+ Integer.toString(index + 1) + "|");
		}
		gclient.cleanup();
		dispose();
	}

	// ******************************************************************
	// put the unique id's into id_vector and names into user_list
	public void write_list(String list) {
		int i, next, n;
		int temp_id;

		user_list.delItems(0, user_list.countItems() - 1);
		user_list.clear();
		id_vector.removeAllElements();
		for (i = 0; i < list.length(); i++) {
			n = list.indexOf('~', i);
			next = list.indexOf('|', i);
			if (next >= list.length() || next == -1)
				break;
			temp_id = Integer.parseInt(list.substring(i, n));
			id_vector.addElement(new Integer(temp_id));

			user_list.addItem(list.substring(n + 1, next));
			i = next;
		}
		// user_list.reshape(258,116,99,176);
	}

	// display the text to the output area of the screen
	public void display(String s) {
		try {
			thread.sleep(100);
		} catch (InterruptedException e) {
		}
		textArea.appendText(s);
	}

	// event handler for GUI components
	public boolean handleEvent(Event evt) {
		int index, storage;

		// when you double-click on a user name in the user_list
		if (evt.id == Event.ACTION_EVENT && evt.target == user_list && !game_on) {
			index = user_list.getSelectedIndex();
			opponent_id = ((Integer) id_vector.elementAt(index)).intValue();
			if (opponent_id != personal_id) {
				display("Challenging " + (String) evt.arg
						+ " to Internet game!\n");
				gclient.send_stream("!!directive!!chlng,"
						+ Integer.toString(personal_id) + "|"
						+ Integer.toString(index + 1) + "|");
			} else
				display("You cannot challenge yourself.\n");
		}

		// when you perform an action while you are connected
		if (evt.id == Event.ACTION_EVENT && gclient.is_connected()) {
			if (gclient.stream_down()) {
				display("A socket error has occured, you are not connected.\n");
				return super.handleEvent(evt);
			}

			if (evt.target == textField) { // if want to send a message to the
											// other player
				String textstream = textField.getText();
				textField.setText("");
				gclient.send_stream(textstream);
			}

		}
		return super.handleEvent(evt);
	}

	public void stop() {

		int index;
		display("Preparing to log off.\n");
		if (game_on) {
			index = id_vector.indexOf(new Integer(opponent_id));
			gclient.send_stream("!!directive!!mssge,surrender|"
					+ Integer.toString(index + 1) + "|");
		}
		gclient.cleanup();
	}

	// ******************************************************************
	// methods to interact with your game class
	// game class calls this to send a move to other player
	// ******************************************************************
	public void sendMove(String text) {
		int index;

		index = id_vector.indexOf(new Integer(opponent_id));
		gclient.send_stream("!!directive!!pmove," + text + "|"
				+ Integer.toString(index + 1) + "|");
	}

	public void acceptyes() {
		int index;

		System.out.println("accept yes");
		// when you hit the Play Opponent button
		display("Opponent ready to Play! You will move second.\n");
		index = id_vector.indexOf(new Integer(opponent_id));
		System.out.println("opponent id is " + opponent_id);
		gclient.send_stream("!!directive!!accpt,"
				+ Integer.toString(personal_id) + "|"
				+ Integer.toString(index + 1) + "|");
		challenged = false;
		game_on = true;
		mygame = new game(myapplet, base, this, false, gameimage);
	}
} // end class

class acceptwindow extends Frame {
	private clientwindow parent;
	private Panel buttonPanel;
	private Button acceptyes;
	private Button acceptno;
	private Label user_label;

	public acceptwindow(clientwindow parent, String wintitle, String User) {
		super(wintitle);
		this.parent = parent;
		user_label = new Label("You have been asked to play with " + User);
		buttonPanel = new Panel();
		acceptyes = new Button("Play Opponent");
		acceptno = new Button("Don't Play Opponent");

		// Add button to panel and panel to window
		setLayout(new FlowLayout());
		buttonPanel.setLayout(new GridLayout(7, 1));
		buttonPanel.add(user_label);
		buttonPanel.add(acceptyes);
		buttonPanel.add(acceptno);
		add(buttonPanel);

		// Size window to preferred size
		this.setSize(300, 300);
		this.show();
	}// end loginwindow

	// uses the jdk1.0.2 event handler...
	public boolean action(Event e, Object arg) {
		if (e.target instanceof Button) {
			if (e.target == acceptyes) {
				if (this.isShowing()) {
					try {
						parent.acceptyes();
					} catch (Exception exceptn) {
						exceptn.printStackTrace();
						System.out.println("Error:" + exceptn);
					} finally {
						this.dispose();
					}
				}
			}
			if (e.target == acceptno) {
				this.dispose();
			}

		}
		return true;
	} // end action(Event, Object)
}// end class definition
